<?php
/*
	Zone Version 1.0
	Zone_App create and run a application MVC
	Created: 28/06/2010
	Updated: 30/06/2011
*/

//Determine module, controller, action and all params
require_once 'Exception.php';

//Ui tiny functions userful
require_once 'Ui.php';

//Hook class
require_once 'App/Config.php';

class Zone_App extends Zone_Config{
	public static $language = NULL;

	public $module	 	= NULL;

	public $controller 	= NULL;

	public $action 		= NULL;

	//store value of request
	public $params 		= array();
	
	function __construct( $baseUrl ){
		//base should be set
		$this->baseUrl = $baseUrl;
		
		//auto get config in apps
		$config = include ROOT.'/apps/config.php';
		$this->setConfig($config);
		
		if( isset( $config['default_timezone'] )){
			date_default_timezone_set($config['default_timezone']);
		}
		
		if( isset( $config['define'] ) ){
			foreach( $config['define'] as $key => $term ){
				defined($key)||define($key,$term);
			}
		}		
		return $this;
	}
		
	//init module from path
	public function bootstrap(){
		//escape and get relative path
		$full_path = $_SERVER['REQUEST_URI'];
		$full_path = substr( $full_path,strlen( $this->baseUrl ));
		$full_path = preg_replace( array('/\?.*$/','/(^\/|\/$)/','/\/(?=\/)/'),'', $full_path );
		
		//rewrite call
		$dir_rw = ROOT.'/apps/rewrite.php';
		if( file_exists($dir_rw)){
			$aRws = include($dir_rw);
			if( is_array( $aRws ) ){
				foreach( $aRws as $k => $aRw ){
					preg_match( $k, $full_path, $match );
					if( $match ){
						$full_path = preg_replace( $k, $aRw[0], $match[0] );
						if( $aRw[1] == "L")	break;
					}	
				}
			}
		}

		//get all params
		defined('ZONE_FULL_URL') || define('ZONE_FULL_URL', $full_path );
		$slots = explode( '/', $full_path );
		
		//url look like language/module/controller/action 
		$language 	= isset( $slots[0] ) && $slots[0] !='' ? ucfirst(strtolower($slots[0])) : '';
		$module		= isset( $slots[1] ) && $slots[1] !=''  ? ucfirst(strtolower($slots[1])) : 'Index';
		$controller = isset( $slots[2] ) && $slots[2] !=''  ? ucfirst(strtolower($slots[2])) : 'Index';
		$action 	= isset( $slots[3] ) && $slots[3] !=''  ? ucfirst(strtolower($slots[3])) : 'Index';
		
		
		$params 	= array();
		$p_start 	= 4;
		
		//Auto check language
		if( is_array($this->config['languages']) && count( $this->config['languages'] ) > 0 ){
			$langs = $this->config['languages'];
			if( !in_array( $language, $langs )){
				if( isset($slots[0]) )
				{
					$langs = $this->config['languages'];
					//replay assign
					$action 		= $controller;
					$controller 	= $module;
					$module 		= $language !='' ? $language : $this->getConfig('defaultModule');	 
					$language		= strtolower( $this->getConfig('defaultLanguage',$langs[0]) );
					$p_start 		= 3;	
				}else{
					if( $debug ){
						throw new App_Exception("Language $langauge is not set");
					}else{
						return $this->setError('404');
					}	
				}
			}
		}else{
			//replay assign
			$langugage		= 'default';
			$action 		= $controller;
			$controller 	= $module;
			$module 		= $language !='' ? $language : ( isset($this->config['defaultModule']) ? $this->config['defaultModule'] : 'Index' );	 
			$p_start 		= 3;	
		}		
		
		//get params
		for( $i= $p_start; $i < count($slots); $i++ ){
			$params[] = $slots[$i];
		}
		
		//assign M-V-C
		$this->language 	= $language;
		$this->module 		= $module;
		$this->controller 	= $controller;
		$this->action 		= $action;	
		$this->params 		= $params;
		return $this;
	}

	//begin load controller	
	public function run( $env = TRUE ){
		//init a string
		$dir = ROOT.'/apps/modules/'.$this->module;
		$debug = isset($this->config['debug']) ? $this->config['debug'] : false;
		
		if( !is_dir( $dir ) ){
			if( $debug ){
				throw new App_Exception("Module {$this->module} is not found");
			}else{
				return $this->setError('404');
			}	
		}
		
		$dir = $dir.'/controllers/'.ucfirst(strtolower($this->controller)).'Controller.php';
		
		if( !file_exists( $dir )){
			if( $debug ){
				throw new App_Exception("$dir is not found");
			}else{
				return $this->setError('404');
			}	
		}else{
			require_once 'App/Action.php';
			require_once $dir;
			
			$name = $this->getControllerName();

			if( class_exists($name) ){
				
				$ctrClass = new $name();
				
				//set language,module,controller,action
				$ctrClass->setLanguage( $this->language );
				$ctrClass->setModule( $this->module );
				$ctrClass->setController( $this->controller );
				$ctrClass->setAction( $this->action );				
				$ctrClass->setConfig( $this->config );				
				$ctrClass->setParams( $this->params );				
				
			}else{
				if( $debug ){
					throw new App_Exception("Class $name of module {$this->module} is not found");
				}else{
					return $this->setError('404');
				}					
			}	

			//check
			$action = $this->action;
			if( !method_exists( $ctrClass, $this->getActionName() ) ){
				if( $debug ){
					throw new App_Exception("Action {$this->getActionName()} of $name controller in {$this->module} module is not found");
				}else{
					return $this->setError('404');
				}
			}
			
			return $ctrClass->run( $env );
		}
	}
	
	
	/*
		Zone simple method
	*/
	public function setModule( $value ){
		$this->module = $value;
	}
	
	public function setController( $value ){
		$this->controller = $value;
	}

	public function setAction( $value ){
		$this->action = $value;
	}

	public function setLanguage( $value ){
		$this->language = $value;
	}

	public function setParams( $params ){
		if( !is_array( $this->params ) ){
			$this->params = array();
		}
		foreach( $params as $k => $p ){
			$this->params[$k] = $p;
		}
		return $this;
	}
	
	public function getActionName(){
		return strtolower($this->action).'Action';
	}
	
	public function getControllerName(){
		return ($this->getModuleName()).ucfirst(strtolower($this->controller)).'Controller';
	}
	
	public function getModuleName(){
		return ucfirst(strtolower($this->module));
	}
	
	public function setError(){
		//header('HTTP/1.1 404 Not Found');
		include ROOT.'/apps/layouts/404.phtml';
		exit;
	}
	
}